<template>
    <div data-tauri-drag-region class="tool-bar-container">
        <div class="logo">
            <img class="logo-img" :src="logoImg" alt="logo">
            <span title="blue-note-editor">青笺编辑器</span>
        </div>
        <div class="tools">
            <div class="tool-item">
                <div class="tool-item-btn" @click="isShowFile=true">文件</div>
                <div class="tool-item-drawer" ref="fileToolRef" v-if="isShowFile">
                    <tool-btn name="新建文件" @click.stop="handleNewFile"></tool-btn>
                    <tool-btn name="新建文件夹" @click.stop="handleNewFolder"></tool-btn>
                    <tool-btn name="打开文件" @click.stop="handleOpenFile"></tool-btn>
                    <tool-btn name="打开文件夹" @click.stop="handleOpenFolder"></tool-btn>
                    <tool-btn name="设置" @click="isOpenSetting=true;isShowFile=false"></tool-btn>
                    <tool-btn name="关于" @click="isOpenAbout=true;isShowFile=false"></tool-btn>
                </div>
            </div>
            <!--            <div class="tool-item">-->
            <!--                <div class="tool-item-btn" @click="isShowEdit=true">编辑</div>-->
            <!--                <div class="tool-item-drawer" ref="editToolRef" v-if="isShowEdit">-->
            <!--                    <tool-btn name="撤销" cut="Ctrl + Z"></tool-btn>-->
            <!--                    <tool-btn name="复制" cut="Ctrl + C"></tool-btn>-->
            <!--                    <tool-btn name="粘贴" cut="Ctrl + V"></tool-btn>-->
            <!--                </div>-->
            <!--            </div>-->
            <div class="tool-item">
                <div class="tool-item-btn" @click="isShowFormat=true">格式</div>
                <div class="tool-item-drawer" ref="formatToolRef" v-show="isShowFormat">
                    <tool-btn name="加粗" cut="Ctrl + B" @click.stop="handleEvents('bold')"></tool-btn>
                    <tool-btn name="删除线" cut="Ctrl + U" @click.stop="handleEvents('del')"></tool-btn>
                    <tool-btn name="下划线" @click.stop="handleEvents('underline')"></tool-btn>
                    <tool-btn name="倾斜" cut="Ctrl + I" @click.stop="handleEvents('italic')"></tool-btn>
                    <tool-btn name="代码块" cut="Ctrl +Alt + C" @click.stop="handleEvents('code')"></tool-btn>
                    <tool-btn name="行内标识" cut="Ctrl +Alt + V" @click.stop="handleEvents('line-sign')"></tool-btn>
                    <div class="tool-divider"></div>
                    <div class="tool-drawer-btn" @click.stop="handleEvents('link')">链接</div>
                    <div class="tool-drawer-btn" @click.stop="handleEvents('table')">表格</div>
                    <tool-btn name="图片" @click.stop="handleUpdateImage"></tool-btn>
                    <input type="file" name="uploadImage" id="uploadImageId" style="display: none"
                           @input="changeUploadImage"/>
                    <div class="tool-drawer-btn" @mouseover="isShowListPop=true" @mouseleave="isShowListPop=false">
                        <span>列表</span>
                        <div class="tool-drawer-pop" v-show="isShowListPop">
                            <div class="tool-drawer-btn" @click.stop="handleEvents('ordered-list')">有序列表</div>
                            <div class="tool-drawer-btn" @click.stop="handleEvents('unordered-list')">无序列表</div>
                        </div>
                    </div>
                    <div class="tool-drawer-btn" @mouseover="isShowTitlePop=true" @mouseleave="isShowTitlePop=false">
                        <span>标题</span>
                        <div class="tool-drawer-pop" v-show="isShowTitlePop">
                            <div class="tool-drawer-btn" @click.stop="handleEvents('one-title')">一级标题</div>
                            <div class="tool-drawer-btn" @click.stop="handleEvents('two-title')">二级标题</div>
                            <div class="tool-drawer-btn" @click.stop="handleEvents('there-title')">三级标题</div>
                            <div class="tool-drawer-btn" @click.stop="handleEvents('four-title')">四级标题</div>
                            <div class="tool-drawer-btn" @click.stop="handleEvents('five-title')">五级标题</div>
                        </div>
                    </div>
                    <div class="tool-divider"></div>
                    <tool-btn name="插入文章尾" @click.stop="isOpenInsertDownFooter=true"></tool-btn>
                </div>
            </div>
            <div class="tool-item">
                <div class="tool-item-btn" @click="isShowAbility=true">功能</div>
                <div class="tool-item-drawer" ref="abilityToolRef" v-show="isShowAbility">
                    <tool-btn name="保存" @click.stop="handleSave"></tool-btn>
                    <tool-btn name="重置" @click.stop="handleReset"></tool-btn>
                    <tool-btn name="查找" cut="Ctrl + F" @click.stop="isOpenSearch=true;isShowAbility=false"></tool-btn>
                </div>
            </div>
            <div class="tool-item">
                <div class="tool-item-btn" @click="isShowTheme=true">主题</div>
                <div class="tool-item-drawer" ref="themeToolRef" v-show="isShowTheme">
                    <tool-btn v-for="theme in markdownThemes" :key="theme.id" :name="theme.name"
                              :cut="theme.author" :check="currentMarkdownTheme===theme.key"
                              @click.stop="handleChangeMarkdownTheme(theme)"></tool-btn>
                </div>
            </div>
            <div class="tool-item">
                <div class="tool-item-btn" @click="isShowCodeTheme=true">代码主题</div>
                <div class="tool-item-drawer" ref="codeThemeToolRef" v-show="isShowCodeTheme">
                    <tool-btn v-for="theme in codeThemeFilter" :key="theme.id" :name="theme.name"
                              :check="theme.key === currentCodeTheme"
                              @click.stop="handleChangeCodeTheme(theme)"></tool-btn>
                    <div class="tool-divider"></div>
                    <tool-btn name="MAC外框" :check="isSetCodeMacBorder"
                              @click.stop="handleSetCodeMacBorder"></tool-btn>
                </div>
            </div>
        </div>
        <div class="right-tools">
            <el-radio-group :model-value="viewDevice" size="small" @change="systemStore.setViewDevice">
                <el-radio-button label="移动端" value="phone">
                    <el-icon>
                        <Cellphone/>
                    </el-icon>
                </el-radio-button>
                <el-radio-button label="浏览器端" value="web">
                    <el-icon>
                        <Monitor/>
                    </el-icon>
                </el-radio-button>
                <el-radio-button label="隐藏" value="none">
                    <el-icon>
                        <Hide/>
                    </el-icon>
                </el-radio-button>
            </el-radio-group>
            <dark-light-switch style="margin-right: 10px"></dark-light-switch>

            <template v-if="!systemStore.isWeb">
                <div class="tool-window-btn" title="最小化" @click.stop="handleMinimizeWindow">
                    <i class="iconfont icon-retract"></i>
                </div>
                <div class="tool-window-btn" title="窗口化" v-if="maximize" @click.stop="handleMaximizeWindow">
                    <i class="iconfont icon-min"></i>
                </div>
                <div class="tool-window-btn" title="最大化" v-else @click.stop="handleMaximizeWindow">
                    <i class="iconfont icon-max"></i>
                </div>
                <div class="tool-window-btn danger" title="关闭" @click="handleCloseWindow">
                    <i class="iconfont icon-close"></i>
                </div>
            </template>
        </div>

        <create-file v-model:open="isOpenCreateFile" :path="createNewFilePath"></create-file>
        <create-folder v-model:open="isOpenCreateFolder"></create-folder>
        <setting-modal v-model:open="isOpenSetting"></setting-modal>
        <about-modal v-model:open="isOpenAbout"></about-modal>
        <search-text-modal v-model:open="isOpenSearch" @searchEvent="handleSearchEvent"></search-text-modal>
        <insert-down-footer v-model:open="isOpenInsertDownFooter"
                            @insertDownFooter="handleInsertDownFooter"></insert-down-footer>
    </div>
</template>

<script setup>
import {Window} from "@tauri-apps/api/window";
import {ref, computed, defineEmits, onMounted, defineExpose} from "vue";
import {storeToRefs} from "pinia";
import {onClickOutside} from '@vueuse/core'
import {Monitor, Cellphone, Hide} from '@element-plus/icons-vue';
import {ElMessage, ElMessageBox} from "element-plus";
import {open} from '@tauri-apps/plugin-dialog';
import {exists, BaseDirectory, readTextFile} from '@tauri-apps/plugin-fs';
import ToolBtn from "./ToolBtn.vue";
import DarkLightSwitch from "./DarkLightSwitch.vue";

import SettingModal from "../views/Setting/index.vue";
import AboutModal from "../views/About/index.vue";
import SearchTextModal from "../components/SearchText.vue";
import CreateFile from "./CreateFile.vue";
import CreateFolder from "./CreateFolder.vue";

import markdownThemes from "../config/markdownThemeConfig.js";
import codeThemes from "../config/codeThemeConfig.js";
import markdownTheme from "../assets/markdownTheme.js";
import codeTheme from "../assets/codeTheme.js";

import {useSystemStore} from "../store/index.js";
import {useFileStore} from "../store/fileStore.js";
import {getCssFile, getSign, isMarkdownFile, getFileName, listToTree} from "../utils/utils.js";
import {updateImage} from "../api/index.js";
import {getFolderFileList, saveDataToFile} from "../utils/clientControl.js";
import InsertDownFooter from "./InsertDownFooter.vue";

import logoImg from "../assets/logo.svg";

const appWindow = new Window('main');

const emit = defineEmits(['handleEvents', 'handleSelectedFile', 'handleClientEvents']);

const isOpenCreateFile = ref(false);
const isOpenCreateFolder = ref(false);
const isOpenSetting = ref(false);
const isOpenAbout = ref(false);
const isOpenSearch = ref(false);
const isOpenInsertDownFooter = ref(false);

const isShowFile = ref(false);
const fileToolRef = ref(null);
const isShowEdit = ref(false);
const editToolRef = ref(null);
const isShowFormat = ref(false);
const formatToolRef = ref(null);
const isShowAbility = ref(false);
const abilityToolRef = ref(null);
const isShowTheme = ref(false);
const themeToolRef = ref(null);
const isShowCodeTheme = ref(false);
const codeThemeToolRef = ref(null);
const isShowTitlePop = ref(false);
const isShowListPop = ref(false);

// 创建新文件路径
const createNewFilePath = ref('');

const systemStore = useSystemStore();
const {maximize, viewDevice} = storeToRefs(systemStore);

const fileStore = useFileStore();

const currentMarkdownTheme = ref('default');
const codeThemeFilter = computed(() => {
    return codeThemes.filter((item, index) => index % 2 === 0);
});
const currentCodeTheme = ref('wechat');
const isSetCodeMacBorder = ref(false);

onMounted(async () => {
    // 读取配置文件数据，写入缓存
    const settingConf = await readTextFile('setting-conf.json', {baseDir: BaseDirectory.AppLocalData});
    const setting = JSON.parse(settingConf);
    systemStore.initSettings(setting);
    fileStore.getTreeDataFromConfig();

    let initMarkdownTheme = markdownThemes.find(item => item.key === systemStore.defaultMarkdownTheme);
    handleChangeMarkdownTheme(initMarkdownTheme);
    let initCodeTheme = codeThemes.find(item => item.key === systemStore.defaultCodeTheme);
    handleChangeCodeTheme(initCodeTheme);
})

onClickOutside(fileToolRef, () => {
    isShowFile.value = false;
})

onClickOutside(editToolRef, () => {
    isShowEdit.value = false;
})

onClickOutside(formatToolRef, () => {
    isShowFormat.value = false;
})

onClickOutside(abilityToolRef, () => {
    isShowAbility.value = false;
})

onClickOutside(themeToolRef, () => {
    isShowTheme.value = false;
})

onClickOutside(codeThemeToolRef, () => {
    isShowCodeTheme.value = false;
})

/**
 * 新建文件方法，直接新建md文件
 * */
function handleNewFile() {
    isOpenCreateFile.value = true;
    createNewFilePath.value = fileStore.fileRootPath;
}

/**
 * 新建文件夹方法
 * */
async function handleNewFolder() {
    isOpenCreateFolder.value = true;
}

/**
 * 打开文件方法，仅允许打开md文件
 * */
async function handleOpenFile() {
    isShowFile.value = false;
    // 选择文件，返回文件地址
    const fileAddress = await open({
        multiple: false,
        directory: false,
        filters: [{
            name: '',
            extensions: ['md']
        }]
    });
    // 不选择跳出
    if (!fileAddress) {
        return;
    }
    // 二次判断md文件
    const isMarkdown = isMarkdownFile(fileAddress);
    if (!isMarkdown) {
        ElMessage({
            message: '仅支持Markdown格式文件!',
            type: 'warning',
        })
        return;
    }
    // 检查文件是否存在
    const hasFile = await exists(fileAddress, {baseDir: BaseDirectory.AppData});
    if (!hasFile) {
        ElMessage({
            message: '当前选择文件不存在，请重新选择!',
            type: 'warning',
        })
        return;
    }
    // 获取文件名
    const fileName = getFileName(fileAddress);
    fileStore.setFileTreeList([
        {
            id: '2133',
            label: fileName,
            leaf: true,
            children: null,
            path: fileAddress
        }
    ])
    // 存一份路径
    systemStore.setOpenDir(fileAddress);
    // 设置默认选中，读取文件内容
    handleClientEvents('selectFile', {address: fileAddress});
}

/**
 * 打开文件夹
 * */
async function handleOpenFolder() {
    isShowFile.value = false;
    // 选择文件，返回文件地址
    const folderAddress = await open({
        multiple: false,
        directory: true,
        filters: [{
            name: '',
            extensions: ['md']
        }]
    });
    // 不选择跳出
    if (!folderAddress) {
        return;
    }
    // 获取文件夹下的文件
    const folderDir = await getFolderFileList(folderAddress);
    // 存一份路径
    systemStore.setOpenDir(folderAddress);
    fileStore.setFileRootPath(folderAddress);
    const folderTreeData = listToTree(folderDir, folderAddress);
    fileStore.setFileTreeList(folderTreeData);
}

/**
 * 操作事件方法
 * @param {string} eventType 事件类型
 * @param {object} eventData 事件数据
 * */
function handleEvents(eventType, eventData) {
    // 点击后关闭按钮
    ['bold', 'del', 'underline', 'italic', 'code', 'line-sign', 'link', 'table', 'ordered-list', 'unordered-list', 'one-title', 'two-title', 'there-title', 'four-title', 'five-title', 'insertDownFooter'].includes(eventType) ? isShowFormat.value = false : '';
    emit('handleEvents', eventType, eventData);
}

/**
 * 操作客户端方法
 * @param {string} eventType 事件类型
 * @param {object} eventData 事件数据
 * */
function handleClientEvents(eventType, eventData) {
    emit('handleClientEvents', eventType, eventData);
}

/** 保存方法 */
function handleSave() {
    handleClientEvents('saveFile')
}

/** 重置方法 */
function handleReset() {
    ElMessageBox.confirm(
        '你确定要重置文档吗?',
        '操作提示',
        {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
        }
    ).then(() => {
        emit('handleEvents', 'reset');
    }).catch(() => {
        console.log('取消')
    })
}

/** 查询弹窗事件 */
function handleSearchEvent(type, data) {
    switch (type) {
        case 'findPrev':
            emit('handleEvents', 'findPrev', data);
            break;
        case 'findNext':
            emit('handleEvents', 'findNext', data);
            break;
        case 'replace':
            emit('handleEvents', 'replace', data);
            break;
        case 'replaceAll':
            emit('handleEvents', 'replaceAll', data);
            break;
        default:
            emit(type, type, data);
    }
}

/** 插入文章尾方法 */
function handleInsertDownFooter(text) {
    handleEvents('insertDownFooter', text);
}

/** 上传图片 */
function handleUpdateImage() {
    isShowFormat.value = false;
    document.querySelector('#uploadImageId').click();
}

/** 上传图片方法 */
function changeUploadImage() {
    const file = document.querySelector('#uploadImageId').files[0];
    let formData = new FormData();
    formData.append('name', file.name);
    formData.append('file', file);
    formData.append('sign', getSign());
    updateImage(formData).then(res => {
        if (res.code === 200) {
            let fileUrl = res.url || res.data?.url;
            if (fileUrl) {
                emit('handleEvents', 'image', fileUrl);
            }
        } else {
            console.error('Upload failed:', res.error || '未知错误');
            ElMessage({
                message: `上传图片错误：${res.error || '请重新上传!'}`,
                type: 'warning',
            });
        }
    })
}

/**
 * 切换主题方法
 * @param {object} theme 主题对象
 * */
async function handleChangeMarkdownTheme(theme) {
    // 移除旧的主题样式
    if (currentMarkdownTheme.value !== '' && !!document.getElementById('markdownTheme')) {
        const oldThemeLink = document.getElementById('markdownTheme');
        oldThemeLink.parentNode.removeChild(oldThemeLink);
    }

    // 设置新的主题样式
    currentMarkdownTheme.value = theme.key;
    const head = document.head || document.getElementsByTagName('head')[0];
    const markdownThemeStyle = markdownTheme[theme.key];
    const style = document.createElement('style');

    style.id = 'markdownTheme';
    style.innerText = markdownThemeStyle;

    head.appendChild(style);
}

/**
 * 切换代码主题方法
 * @param {object} theme 主题对象
 * */
function handleChangeCodeTheme(theme) {
    if (theme.key.indexOf('_mac') > -1) {
        currentCodeTheme.value = theme.key.split('_')[0];
        isSetCodeMacBorder.value = true;
    } else {
        currentCodeTheme.value = theme.key;
    }
    SetCodeTheme();
}

/** 设置代码 MAC 边框 */
function handleSetCodeMacBorder() {
    isSetCodeMacBorder.value = !isSetCodeMacBorder.value;
    SetCodeTheme();
}

/** 设置代码主题 */
async function SetCodeTheme() {
    if (currentCodeTheme.value !== '' && !!document.getElementById('codeTheme')) {
        let oldCodeTheme = document.getElementById('codeTheme');
        oldCodeTheme.parentNode.removeChild(oldCodeTheme);
    }
    const head = document.head || document.getElementsByTagName('head')[0];
    const codeThemePath = isSetCodeMacBorder.value ? currentCodeTheme.value + '_mac' : currentCodeTheme.value;
    const codeThemeStyle = codeTheme[codeThemePath];
    const style = document.createElement('style');

    style.id = 'codeTheme';
    style.innerText = codeThemeStyle;

    head.appendChild(style);
}

/** 最小化窗口（针对桌面端生效） */
function handleMinimizeWindow() {
    appWindow.minimize();
}

/** 切换窗口化/最大化 */
async function handleMaximizeWindow() {
    await appWindow.toggleMaximize();
    systemStore.toggleMaximize();
}

/** 关闭窗口（针对桌面端生效） */
function handleCloseWindow() {
    if (systemStore.closeMethod === 'close') {
        appWindow.close();
    } else if (systemStore.closeMethod === 'hide') {
        appWindow.hide();
    }
}

defineExpose({isOpenSetting, isOpenCreateFile, createNewFilePath});
</script>

<style scoped lang="less">
.tool-bar-container {
    width: 100%;
    height: 40px;
    box-shadow: 0 4px 10px rgba(0, 0, 0, .05);
    padding: 0 10px;
    box-sizing: border-box;
    background-color: #fff;
    position: fixed;
    top: 0;
    left: 0;
    z-index: 99;
    display: flex;
}

.logo {
    height: 40px;
    display: flex;
    justify-content: flex-start;
    align-items: center;
    cursor: default;
    margin-right: 10px;

    .logo-img {
        width: 24px;
        height: 24px;
        margin-right: 8px;
    }
}

.tools {
    height: 40px;
    font-size: 14px;
    color: #333;
    display: flex;

    .tool-item {
        position: relative;
    }

    .tool-item-btn {
        height: 40px;
        line-height: 40px;
        padding: 0 14px;
        box-sizing: border-box;
        cursor: pointer;

        &:hover {
            background-color: rgba(136, 136, 136, 0.2);
        }
    }

    .tool-item-drawer {
        width: 180px;
        background-color: #fff;
        position: absolute;
        top: 40px;
        left: 0;

        .tool-drawer-btn {
            padding: 4px 20px;
            box-sizing: border-box;
            background-color: #fff;
            transition: all 0.2s;
            cursor: pointer;
            position: relative;

            &:hover {
                background-color: rgba(136, 136, 136, 0.15);
            }
        }
    }
}

.tool-drawer-pop {
    position: absolute;
    top: 50%;
    right: 0;
    transform: translate(100%, -50%);
}

.tool-divider {
    display: block;
    height: 1px;
    width: 100%;
    background-color: #dcdfe6;
}

.right-tools {
    height: 40px;
    display: flex;
    align-items: center;
    gap: 10px;
    position: absolute;
    top: 0;
    right: 0;
}

.tool-switch {
    font-size: 10px;
}

.tool-window-btn {
    width: 40px;
    height: 40px;
    display: flex;
    justify-content: center;
    align-items: center;
    cursor: pointer;
    color: #333;

    &:hover {
        background-color: #eee;
    }

    &.danger:hover {
        color: #fff;
        background-color: #dc3545;
    }
}
</style>